
# -*- coding: utf-8 -*-

import debug
import logging
import datetime
from SeBase import SeBase
from pymongo import Connection
import bson
import gridfs

class SeMongodb(SeBase):
    @debug.entry
    def __init__(self, config=None):
        '''
            <TODO>
                コンフィグ読み込みや永続化が必要なストレージ接続を行う
        '''
        self.config = config
        self.__read_config(self.config)

        self.dbs           = Connection(self.host);
        self.db_collection = self.dbs[self.database][self.collection]
        self.db_gridfs     = gridfs.GridFS(self.dbs[self.database])

    def __read_config(self, config):
        '''
            <TODO>
                ストレージ接続に必要な情報を読み込む
        '''
        self.host       = config['object'].get(self.__class__.__name__, 'host')
        self.database   = config['object'].get(self.__class__.__name__, 'database')
        self.collection = config['object'].get(self.__class__.__name__, 'collection')
        self.async      = config['object'].get(self.__class__.__name__, 'async')

    @debug.entry
    def get_frame_list_all(self, target, fext='.jpg'):
        '''
            <TODO>
                ストレージに保存されたフレームリストを返す
            target : カメラID
            return : パス、拡張子を含まないリスト(全件)
                ex)
                    target@YYYY-mm-ddTHH:MM:SS.ffffffZ
        '''
        query    = {
                    'CID':target,
                    'Fext': fext,
        }
        docs = self.db_collection.find(query).sort('CreateDate')
        items = []
        for doc in docs:
            item = doc['CID'] + '@' + \
            doc['CreateDate'].strftime('%Y-%m-%dT%H:%M:%S.%fZ')
            items.append(item)

        return items

    @debug.entry
    def get_frame_list_first(self, target, fext='.jpg'):
        '''
            <TODO>
                ストレージに保存されたフレームで一番古いものを返す
            target : カメラID
            return : パス、拡張子を含まないリスト(1件)
                ex)
                    target@YYYY-mm-ddTHH:MM:SS.ffffffZ
        '''
        query    = {
                    'CID':target,
                    'Fext': fext,
        }
        docs = self.db_collection.find(query).sort('CreateDate').limit(1)
        items = []
        for doc in docs:
            item = doc['CID'] + '@' + \
            doc['CreateDate'].strftime('%Y-%m-%dT%H:%M:%S.%fZ')
            items.append(item)

        return items

    @debug.entry
    def get_frame_list_last(self, target, fext='.jpg'):
        '''
            <TODO>
                ストレージに保存されたフレームで一番新しいものを返す
            target : カメラID
            return : パス、拡張子を含まないリスト(1件)
                ex)
                    target@YYYY-mm-ddTHH:MM:SS.ffffffZ
        '''
        query    = {
                    'CID':target,
                    'Fext': fext,
        }
        docs = self.db_collection.find(query).sort('CreateDate',-1).limit(1)
        items = []
        for doc in docs:
            item = doc['CID'] + '@' + \
            doc['CreateDate'].strftime('%Y-%m-%dT%H:%M:%S.%fZ')
            items.append(item)

        return items

    @debug.entry
    def get_frame_list_range(self, target, query, fext='.jpg'):
        '''
            <TODO>
                ストレージに保存されたフレームの時間範囲で返す
            target : カメラID
            query  : list(termfrom, termto)
            return : パス、拡張子を含まないリスト(N件)
                ex)
                    target@YYYY-mm-ddTHH:MM:SS.ffffffZ
        '''
        termfrom = datetime.datetime.strptime(query[0], '%Y-%m-%dT%H:%M:%S.%fZ')
        termto   = datetime.datetime.strptime(query[1], '%Y-%m-%dT%H:%M:%S.%fZ')
        query    = {
                    'CID':target,
                    'Fext':fext,
                    'CreateDate':{'$gte':termfrom, '$lte':termto},
        }
        docs = self.db_collection.find(query).sort('CreateDate')
        items = []
        for doc in docs:
            item = doc['CID'] + '@' + \
            doc['CreateDate'].strftime('%Y-%m-%dT%H:%M:%S.%fZ')
            items.append(item)

        return items

    @debug.entry
    def save_frame(self, target, fileobj, fext='.jpg', uniqname=None, options={'async':False} ):
        '''
            <TODO>
                ストレージにフレームを保存する
            target   : カメラID
            fileobj  : 保存するオブジェクト
            uniqname : reserved
            options  : reserved
        '''
        if uniqname:
            filename = target + '@' + uniqname
        else:
            today = datetime.datetime.today()
            filename = target + '@' + today.strftime('%Y-%m-%dT%H:%M:%S.%fZ') + fext
        logging.info("save_frame : %s" % filename)

        gridfs_id = self.db_gridfs.put(fileobj, filename=filename)
        self.db_collection.insert({
            'CreateDate':today,
            'CID': target,
            'Fext': fext,
            'File': gridfs_id
        })

    @debug.entry
    def get_frame(self, framestring, fext='.jpg'):
        '''
            <TODO>
                ストレージに格納されたフレームの実体を返す
            target      : カメラID
            framestring : クエリ結果のフレームを示す文字列
            return      : フレームの実体
        '''
        string_div = framestring.split('@')
        target     = string_div[0]
        datestring = string_div[1].replace(fext,'')
        
        query    = {
                    'CID':target,
                    'Fext': fext,
                    'CreateDate':datetime.datetime.strptime(datestring, '%Y-%m-%dT%H:%M:%S.%fZ')
        }
        doc = self.db_collection.find_one(query)
        if not self.db_gridfs.exists(doc['File']):
            return None

        return self.db_gridfs.get(doc['File']).read()

